GDK W32: Ensure that selection request is processed
authorРуслан Ижбулатов <lrn1986@gmail.com>
Mon, 18 Sep 2017 16:49:11 +0000 (16:49 +0000)
committerРуслан Ижбулатов <lrn1986@gmail.com>
Sat, 2 Dec 2017 10:38:37 +0000 (10:38 +0000)
To do that, run the message loop for one second or until the side-effect
of running the selection request handler is achieved (as opposed to
running it until the event is no longer queued).

The disavantage of this method is that if the event handling is
somehow missed (due to a variety of reasons - after all, it's not
a straight path from an event being queued to property_change()
being called), this will loop for one second. Since we do process
events during that time, this will not hang the application, but
might still restrict some of the functionality.

https://bugzilla.gnome.org/show_bug.cgi?id=786509

gdk/win32/gdkdnd-win32.c
gdk/win32/gdkselection-win32.c

index daba91e888630dc073308fa3258e22786dabe88e..ab10892ff9ffa29eca7eda60f87eb674da914957 100644 (file)
@@ -1042,6 +1042,7 @@ idataobject_getdata (LPDATAOBJECT This,
   GdkEvent e;
   gint i;
   GdkAtom target;
+  gint64 loopend;
 
   GDK_NOTE (DND, g_print ("idataobject_getdata %p %s ",
                          This, _gdk_win32_cf_to_string (pFormatEtc->cfFormat)));
@@ -1105,10 +1106,12 @@ idataobject_getdata (LPDATAOBJECT This,
 
   gdk_event_put (&e);
 
-  process_pending_events (gdk_device_get_display (gdk_drag_context_get_device (ctx->context)));
+  /* Don't hold up longer than one second */
+  loopend = g_get_monotonic_time () + 1000000000;
 
-  win32_sel->property_change_format = 0;
-  win32_sel->property_change_data = 0;
+  while (win32_sel->property_change_data != 0 &&
+         g_get_monotonic_time () < loopend)
+    process_pending_events (gdk_device_get_display (gdk_drag_context_get_device (ctx->context)));
 
   if (pMedium->hGlobal == NULL) {
     GDK_NOTE (DND, g_print (" E_UNEXPECTED\n"));
index a164bb9020a9a4b513b14cf4159138c630e4975b..879b90d0b92e96e9a746779c0265f8cb0b3b7714 100644 (file)
@@ -2393,6 +2393,9 @@ _gdk_win32_selection_property_change (GdkWin32Selection *win32_sel,
 
           g_free (set_data);
         }
+
+      win32_sel->property_change_format = 0;
+      win32_sel->property_change_data = 0;
     }
   else
     {